package com.xbts.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xbts.common.constant.UserConstants;
import com.xbts.common.core.domain.BaseEntity;
import com.xbts.common.core.domain.entity.SysUser;
import com.xbts.common.core.page.PageDomain;
import com.xbts.common.core.page.TableSupport;
import com.xbts.common.exception.ServiceException;
import com.xbts.common.utils.DateUtils;
import com.xbts.common.utils.SecurityUtils;
import com.xbts.common.utils.StringUtils;
import com.xbts.system.domain.PartyActiveManage;
import com.xbts.system.domain.PartyArea;
import com.xbts.system.domain.PartyPointsDeclaration;
import com.xbts.system.domain.PartyPointsDeclarationStatistics;
import com.xbts.system.domain.vo.PartyPointsDeclarationVo;
import com.xbts.system.mapper.PartyPointsDeclarationMapper;
import com.xbts.system.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 积分申报表Service业务层处理
 *
 * @author xbts
 * @date 2023-06-12
 */
@Service
public class PartyPointsDeclarationServiceImpl extends ServiceImpl<PartyPointsDeclarationMapper, PartyPointsDeclaration>
        implements IPartyPointsDeclarationService {

    @Resource
    private IPartyActiveManageService partyActiveManageService;
    @Resource
    private IPartyAreaService partyAreaService;
    @Resource
    private IPartyPointsDeclarationStatisticsService partyPointsDeclarationStatisticsService;
    @Resource
    private ISysUserService userService;


    /**
     * 查询积分申报列表
     *
     * @param partyPointsDeclaration 积分申报
     * @return 积分申报
     */
    @Override
    public List<PartyPointsDeclaration> selectPartyPointsDeclarationList(PartyPointsDeclaration partyPointsDeclaration) {

        QueryWrapper<PartyPointsDeclaration> queryWrapper = partyPointsDeclaration.queryWrapper();
        // 联络员才加权限
        if (SecurityUtils.getLoginUser().getUser().getUserType().equals(UserConstants.USER_TYPE_LLY)) {
            String userId = null;
            String createBy = partyPointsDeclaration.getCreateBy();
            if (StringUtils.isNotBlank(createBy)) {
                userId = createBy;
            } else {
                userId = SecurityUtils.getUserId().toString();
            }
            queryWrapper.eq("create_by", userId);
        }

        // 活动创建时间筛选
        Map<String, Object> params = partyPointsDeclaration.getParams();
        if (Objects.nonNull(params)) {
            // 活动创建时间筛选
            if (params.containsKey("startTime") && StringUtils.isNotBlank(params.get("startTime").toString())) {
                queryWrapper.ge("active_join_time", params.get("startTime").toString());
            }
            // 活动结束时间筛选
            if (params.containsKey("endTime") && StringUtils.isNotBlank(params.get("endTime").toString())) {
                queryWrapper.le("active_join_time", params.get("endTime").toString());
            }
        }
        // 先按照状态为0的排序，然后有更新时间按更新时间排序否则按创建时间排序
//        queryWrapper.last(" ORDER BY if(status=0, 99, IFNULL(update_time, create_time)) desc");
        queryWrapper.last(" ORDER BY IFNULL( update_time, create_time ) DESC");
        List<PartyPointsDeclaration> list = list(queryWrapper);

        if (!list.isEmpty()) {
            List<String> userIds = list.stream().map(BaseEntity::getCreateBy).collect(Collectors.toList());
            List<SysUser> sysUsers = userService.listByIds(userIds);
            Map<String, String> sysUserMap = sysUsers.stream().collect(Collectors.toMap(v1 -> v1.getUserId().toString(), SysUser::getNickName));
            for (PartyPointsDeclaration pointsDeclaration : list) {
                pointsDeclaration.setUserNickName(sysUserMap.get(pointsDeclaration.getCreateBy()));
            }
        }
        return list;
    }

    /**
     * 查询积分申报
     *
     * @param id 积分申报主键
     * @return 积分申报
     */
    @Override
    public PartyPointsDeclaration selectPartyPointsDeclarationById(String id) {
        return getById(id);
    }

    /**
     * 新增积分申报
     *
     * @param partyPointsDeclaration 积分申报
     * @return 结果
     */
    @Override
    public boolean insertPartyPointsDeclaration(PartyPointsDeclaration partyPointsDeclaration) {
        if (SecurityUtils.isAdmin()) {
            throw new ServiceException("管理员不能申报积分!");
        }
        String activityCode = partyPointsDeclaration.getActivityCode();
        PartyActiveManage partyActiveManage = partyActiveManageService.getById(activityCode);
        if (Objects.isNull(partyActiveManage)) {
            throw new ServiceException("活动不存在!");
        }

        // 申报人
//        partyPointsDeclaration.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        partyPointsDeclaration.setCreateBy(SecurityUtils.getUserId().toString());
        // 申报时间
        partyPointsDeclaration.setCreateTime(DateUtils.getNowDate());
        // 申报年份
        partyPointsDeclaration.setDeclarationYear(DateUtils.parseDateToStr(DateUtils.YYYY, partyPointsDeclaration.getActiveJoinTime()));
        // 审核状态（0待审核 1通过 2驳回）
        partyPointsDeclaration.setStatus("0");
        // 活动开始时间
        partyPointsDeclaration.setActiveCreateTime(partyActiveManage.getCreateTime());
        partyPointsDeclaration.setActivityClassification(partyActiveManage.getActivityClassification());
        partyPointsDeclaration.setDefaultRewardPoints(partyActiveManage.getRewardPoints());
        String belongToArea = SecurityUtils.getLoginUser().getUser().getBelongToArea();
        if (StringUtils.isBlank(belongToArea)) {
            throw new ServiceException("当前用户没有片区信息!");
        }
        //查询片区名称
        PartyArea partyArea = partyAreaService.getById(belongToArea);
        partyPointsDeclaration.setBelongToArea(belongToArea);
        partyPointsDeclaration.setAreaName(partyArea.getAreaName());
        return save(partyPointsDeclaration);
    }

    /**
     * 修改积分申报
     *
     * @param partyPointsDeclaration 积分申报
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePartyPointsDeclaration(PartyPointsDeclaration partyPointsDeclaration) {
        PartyPointsDeclaration declaration = getById(partyPointsDeclaration.getId());

        if (!"0".equals(declaration.getStatus())) {
            throw new ServiceException("已审核通过的积分不能修改!");
        }

        Double rewardPoints = partyPointsDeclaration.getRewardPoints();
        String activityCode = declaration.getActivityCode();
        PartyActiveManage partyActiveManage = partyActiveManageService.getById(activityCode);
        if (Objects.isNull(partyActiveManage)) {
            throw new ServiceException("活动不存在!");
        }

        declaration.setUpdateBy(SecurityUtils.getUserId().toString());
        declaration.setUpdateTime(DateUtils.getNowDate());
        // 默认积分为活动积分
        if (Objects.isNull(rewardPoints)) {
            rewardPoints = partyActiveManage.getRewardPoints();
            declaration.setRewardPoints(rewardPoints);
        } else {
            if (rewardPoints > partyActiveManage.getRewardPoints()) {
                throw new ServiceException("填写积分不能大于活动积分!");
            }
        }

        if ("2".equals(partyPointsDeclaration.getStatus())) {
            // 拒绝理由
            if (StringUtils.isNotBlank(partyPointsDeclaration.getRejectReason())) {
                declaration.setRejectReason(partyPointsDeclaration.getRejectReason());
            } else {
                throw new ServiceException("拒绝理由不能为空!");
            }
        } else if ("1".equals(partyPointsDeclaration.getStatus())) {
            declaration.setRewardPoints(rewardPoints);
        }

        declaration.setStatus(partyPointsDeclaration.getStatus());
        boolean update = updateById(declaration);
        if (update && "1".equals(declaration.getStatus())) {//申报人id，年份，活动编号，审核状态
            PartyPointsDeclarationStatistics partyPointsDeclarationStatistics = new PartyPointsDeclarationStatistics();
            partyPointsDeclarationStatistics.setYear(declaration.getDeclarationYear());
            partyPointsDeclarationStatistics.setUpdateTime(DateUtils.getNowDate());
            partyPointsDeclarationStatistics.setRewardPoints(rewardPoints);
            partyPointsDeclarationStatistics.setBelongToArea(declaration.getBelongToArea());
            partyPointsDeclarationStatisticsService.savePartyPointsDeclarationStatistics(partyPointsDeclarationStatistics);
        }
        return update;
    }

    /**
     * 批量删除积分申报
     *
     * @param ids 需要删除的积分申报主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePartyPointsDeclarationByIds(List<String> ids) {
        // 删除积分申报后，需要更新积分统计表
        //查询各个片区的积分
        QueryWrapper<PartyPointsDeclaration> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(reward_points) reward_points, belong_to_area, declaration_year, status");
        queryWrapper.in("id", ids);
        queryWrapper.groupBy("belong_to_area, declaration_year");
        List<PartyPointsDeclaration> list = list(queryWrapper);

        //获取审核通过的列表
        List<PartyPointsDeclaration> passList = list.stream().filter(f -> "1".equals(f.getStatus())).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(passList)) {
            for (PartyPointsDeclaration partyPointsDeclaration : passList) {
                Double rewardPoints = partyPointsDeclaration.getRewardPoints();//积分
                String belongToArea = partyPointsDeclaration.getBelongToArea();//片区
                String declarationYear = partyPointsDeclaration.getDeclarationYear(); //年份

                LambdaQueryWrapper<PartyPointsDeclarationStatistics> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                lambdaQueryWrapper.eq(PartyPointsDeclarationStatistics::getBelongToArea, belongToArea);
                lambdaQueryWrapper.eq(PartyPointsDeclarationStatistics::getYear, declarationYear);
                PartyPointsDeclarationStatistics partyPointsDeclarationStatistics = partyPointsDeclarationStatisticsService.getOne(lambdaQueryWrapper);
                if (Objects.isNull(partyPointsDeclarationStatistics)) {
                    continue;
                }
                Double rewardPoints1 = partyPointsDeclarationStatistics.getRewardPoints();
                rewardPoints1 = rewardPoints1 - rewardPoints;
                if (rewardPoints1 < 0) {
                    rewardPoints1 = 0D;
                }
                partyPointsDeclarationStatistics.setRewardPoints(rewardPoints1);
                partyPointsDeclarationStatisticsService.updateById(partyPointsDeclarationStatistics);
            }
        }
        return removeBatchByIds(ids);
    }

    /**
     * 删除积分申报信息
     *
     * @param id 积分申报主键
     * @return 结果
     */
    @Transactional
    @Override
    public boolean deletePartyPointsDeclarationById(String id) {
        return removeById(id);
    }

    /**
     * 积分排行
     *
     * @param year 年份
     * @return 积分排行
     */
    @Override
    public List<PartyPointsDeclarationVo> pointsRanking(String year) {
        //默认当前年份
        if (StringUtils.isBlank(year)) {
            year = DateUtils.getYear();
        }
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();// 2
        Integer pageSize = pageDomain.getPageSize();// 10

        List<PartyPointsDeclarationVo> partyPointsDeclarationVos = baseMapper.pointsRanking(year);

        // 手动排名
        int size = 1;
        for (PartyPointsDeclarationVo partyPointsDeclarationVo : partyPointsDeclarationVos) {
            int ranking = (pageNum - 1) * pageSize + size;
            partyPointsDeclarationVo.setRanking(ranking);
            size++;
        }
        return partyPointsDeclarationVos;
    }

}
